const START_YEAR = 1900; //定义数据起始年份（公历）
const END_YEAR = 2100; //定义数据终止年份（不包含该年）

//1899年农历十月及以后的闰月索引，对应cPreMonth中的序号
//当前为-1，表示1899年农历十月以后无闰月。
const cPreLeapIndex = -1;

//1899年农历十月及以后的月份，每月初一在1900年的年内序数。
//cPreMonth中分别对应农历的十月、十一月、十二月、正月。
const cPreMonth = [-59, -29, 0, 30];

//农历月份信息。一年用3个字节表示
//+-------------------------------------------------------------------------+
//| 第23位 |        第22-17位       |  第16-13位 |         第12-0位         |
//|--------+------------------------+------------+--------------------------|
//|  保留  | 农历正月初一的年内序数 |    闰月    | 一个比特对应一个月份大小 |
//+-------------------------------------------------------------------------+
//月份大小数据是月份小的在低位，月份大的在高位，即正月在最低位。
//以1900年为例，3个字节的数据展开成二进制位：
//  0       011110        1000                     1 0 1 1 0 1 1 0 1 0 0 1 0
//保留  1月31日（春节）  闰八月   从左往右依次十二月，十一月……闰八月、八月、七月……正月的天数
//农历月份对应的位为0，表示这个月为29天（小月），为1表示有30天（大月）。
const byMonthInfo = [
	0x3D, 0x16, 0xD2, 0x62, 0x07, 0x52, 0x4C, 0x0E, 0xA5, 0x38, 0xB6, 0x4A, 0x5C, 0x06, 0x4B, //1900-1904
	0x44, 0x0A, 0x9B, 0x30, 0x95, 0x56, 0x56, 0x05, 0x6A, 0x40, 0x0B, 0x59, 0x2A, 0x57, 0x52, //1905-1909
	0x50, 0x07, 0x52, 0x3A, 0xDB, 0x25, 0x60, 0x0B, 0x25, 0x48, 0x0A, 0x4B, 0x32, 0xB4, 0xAB, //1910-1914
	0x58, 0x02, 0xAD, 0x42, 0x05, 0x6B, 0x2C, 0x4B, 0x69, 0x52, 0x0D, 0xA9, 0x3E, 0xFD, 0x92, //1915-1919
	0x64, 0x0E, 0x92, 0x4C, 0x0D, 0x25, 0x36, 0xBA, 0x4D, 0x5C, 0x0A, 0x56, 0x46, 0x02, 0xB6, //1920-1924
	0x2E, 0x95, 0xB5, 0x56, 0x06, 0xD4, 0x40, 0x0E, 0xA9, 0x2C, 0x5E, 0x92, 0x50, 0x0E, 0x92, //1925-1929
	0x3A, 0xCD, 0x26, 0x5E, 0x05, 0x2B, 0x48, 0x0A, 0x57, 0x32, 0xB2, 0xB6, 0x58, 0x0B, 0x5A, //1930-1934
	0x44, 0x06, 0xD4, 0x2E, 0x6E, 0xC9, 0x52, 0x07, 0x49, 0x3C, 0xF6, 0x93, 0x62, 0x0A, 0x93, //1935-1939
	0x4C, 0x05, 0x2B, 0x34, 0xCA, 0x5B, 0x5A, 0x0A, 0xAD, 0x46, 0x05, 0x6A, 0x30, 0x9B, 0x55, //1940-1944
	0x56, 0x0B, 0xA4, 0x40, 0x0B, 0x49, 0x2A, 0x5A, 0x93, 0x50, 0x0A, 0x95, 0x38, 0xF5, 0x2D, //1945-1949
	0x5E, 0x05, 0x36, 0x48, 0x0A, 0xAD, 0x34, 0xB5, 0xAA, 0x58, 0x05, 0xB2, 0x42, 0x0D, 0xA5, //1950-1954
	0x2E, 0x7D, 0x4A, 0x54, 0x0D, 0x4A, 0x3D, 0x0A, 0x95, 0x60, 0x0A, 0x97, 0x4C, 0x05, 0x56, //1955-1959
	0x36, 0xCA, 0xB5, 0x5A, 0x0A, 0xD5, 0x46, 0x06, 0xD2, 0x30, 0x8E, 0xA5, 0x56, 0x0E, 0xA5, //1960-1964
	0x40, 0x06, 0x4A, 0x28, 0x6C, 0x97, 0x4E, 0x0A, 0x9B, 0x3A, 0xF5, 0x5A, 0x5E, 0x05, 0x6A, //1965-1969
	0x48, 0x0B, 0x69, 0x34, 0xB7, 0x52, 0x5A, 0x0B, 0x52, 0x42, 0x0B, 0x25, 0x2C, 0x96, 0x4B, //1970-1974
	0x52, 0x0A, 0x4B, 0x3D, 0x14, 0xAB, 0x60, 0x02, 0xAD, 0x4A, 0x05, 0x6D, 0x36, 0xCB, 0x69, //1975-1979
	0x5C, 0x0D, 0xA9, 0x46, 0x0D, 0x92, 0x30, 0x9D, 0x25, 0x56, 0x0D, 0x25, 0x41, 0x5A, 0x4D, //1980-1984
	0x64, 0x0A, 0x56, 0x4E, 0x02, 0xB6, 0x38, 0xC5, 0xB5, 0x5E, 0x06, 0xD5, 0x48, 0x0E, 0xA9, //1985-1989
	0x34, 0xBE, 0x92, 0x5A, 0x0E, 0x92, 0x44, 0x0D, 0x26, 0x2C, 0x6A, 0x56, 0x50, 0x0A, 0x57, //1990-1994
	0x3D, 0x14, 0xD6, 0x62, 0x03, 0x5A, 0x4A, 0x06, 0xD5, 0x36, 0xB6, 0xC9, 0x5C, 0x07, 0x49, //1995-1999
	0x46, 0x06, 0x93, 0x2E, 0x95, 0x2B, 0x54, 0x05, 0x2B, 0x3E, 0x0A, 0x5B, 0x2A, 0x55, 0x5A, //2000-2004
	0x4E, 0x05, 0x6A, 0x38, 0xFB, 0x55, 0x60, 0x0B, 0xA4, 0x4A, 0x0B, 0x49, 0x32, 0xBA, 0x93, //2005-2009
	0x58, 0x0A, 0x95, 0x42, 0x05, 0x2D, 0x2C, 0x8A, 0xAD, 0x50, 0x0A, 0xB5, 0x3D, 0x35, 0xAA, //2010-2014
	0x62, 0x05, 0xD2, 0x4C, 0x0D, 0xA5, 0x36, 0xDD, 0x4A, 0x5C, 0x0D, 0x4A, 0x46, 0x0C, 0x95, //2015-2019
	0x30, 0x95, 0x2E, 0x54, 0x05, 0x56, 0x3E, 0x0A, 0xB5, 0x2A, 0x55, 0xB2, 0x50, 0x06, 0xD2, //2020-2024
	0x38, 0xCE, 0xA5, 0x5E, 0x07, 0x25, 0x48, 0x06, 0x4B, 0x32, 0xAC, 0x97, 0x56, 0x0C, 0xAB, //2025-2029
	0x42, 0x05, 0x5A, 0x2C, 0x6A, 0xD6, 0x52, 0x0B, 0x69, 0x3D, 0x77, 0x52, 0x62, 0x0B, 0x52, //2030-2034
	0x4C, 0x0B, 0x25, 0x36, 0xDA, 0x4B, 0x5A, 0x0A, 0x4B, 0x44, 0x04, 0xAB, 0x2E, 0xA5, 0x5B, //2035-2039
	0x54, 0x05, 0xAD, 0x3E, 0x0B, 0x6A, 0x2A, 0x5B, 0x52, 0x50, 0x0D, 0x92, 0x3A, 0xFD, 0x25, //2040-2044
	0x5E, 0x0D, 0x25, 0x48, 0x0A, 0x55, 0x32, 0xB4, 0xAD, 0x58, 0x04, 0xB6, 0x40, 0x05, 0xB5, //2045-2049
	0x2C, 0x6D, 0xAA, 0x52, 0x0E, 0xC9, 0x3F, 0x1E, 0x92, 0x62, 0x0E, 0x92, 0x4C, 0x0D, 0x26, //2050-2054
	0x36, 0xCA, 0x56, 0x5A, 0x0A, 0x57, 0x44, 0x05, 0x56, 0x2E, 0x86, 0xD5, 0x54, 0x07, 0x55, //2055-2059
	0x40, 0x07, 0x49, 0x28, 0x6E, 0x93, 0x4E, 0x06, 0x93, 0x38, 0xF5, 0x2B, 0x5E, 0x05, 0x2B, //2060-2064
	0x46, 0x0A, 0x5B, 0x32, 0xB5, 0x5A, 0x58, 0x05, 0x6A, 0x42, 0x0B, 0x65, 0x2C, 0x97, 0x4A, //2065-2069
	0x52, 0x0B, 0x4A, 0x3D, 0x1A, 0x95, 0x62, 0x0A, 0x95, 0x4A, 0x05, 0x2D, 0x34, 0xCA, 0xAD, //2070-2074
	0x5A, 0x0A, 0xB5, 0x46, 0x05, 0xAA, 0x2E, 0x8B, 0xA5, 0x54, 0x0D, 0xA5, 0x40, 0x0D, 0x4A, //2075-2079
	0x2A, 0x7C, 0x95, 0x4E, 0x0C, 0x96, 0x38, 0xF9, 0x4E, 0x5E, 0x05, 0x56, 0x48, 0x0A, 0xB5, //2080-2084
	0x32, 0xB5, 0xB2, 0x58, 0x06, 0xD2, 0x42, 0x0E, 0xA5, 0x2E, 0x8E, 0x4A, 0x50, 0x06, 0x8B, //2085-2089
	0x3B, 0x0C, 0x97, 0x60, 0x04, 0xAB, 0x4A, 0x05, 0x5B, 0x34, 0xCA, 0xD6, 0x5A, 0x0B, 0x6A, //2090-2094
	0x46, 0x07, 0x52, 0x30, 0x97, 0x25, 0x54, 0x0B, 0x45, 0x3E, 0x0A, 0x8B, 0x28, 0x54, 0x9B //2095-2099
];

//二十四节气信息。一年用6个字节表示，每个节气使用两比特数据。
//+-------------------------------------------------------+
//| 第一字节最高两位 |  第一字节其余6位至第六字节共46个位 |
//|------------------+------------------------------------|
//|小寒的年内序数减3 | 每个节气距离上一节气的天数，共23组 |
//+-------------------------------------------------------+
//小寒的年内序数已给出，剩下的23个节气分别对应这23组数据，有以下含义：
//+-------------------------------------------------------+
//|  二进制位 | 意义 |                描述                |
//|-----------+------+------------------------------------|
//|     00    | 14天 |  当前对应的节气距离上一节气为14天  |
//|-----------+------+------------------------------------|
//|     01    | 15天 |  当前对应的节气距离上一节气为15天  |
//|-----------+------+------------------------------------|
//|     10    | 16天 |  当前对应的节气距离上一节气为16天  |
//|-----------+------+------------------------------------|
//|     11    | 17天 |  当前对应的节气距离上一节气为17天  |
//+-------------------------------------------------------+
//由上表可以看出，除小寒以外的其余23个节气的两比特数据加上14就是距离上一节气的天数。
//节气顺序：
//小寒 大寒 立春 雨水 惊蛰 春分 清明 谷雨 立夏 小满 芒种 夏至
//小暑 大暑 立秋 处暑 白露 秋分 寒露 霜降 立冬 小雪 大雪 冬至

//节气数据将由“wSTSource[36]”和“bySTIndex[600]”中的数据生成。
const wSTSource = [
	0x1555, 0x4555, 0x5155, 0x5156, 0x5456, 0x5459, 0x5519, 0x5525, 0x5555, 0x5951, //0-9
	0x5954, 0x5A9A, 0x6554, 0x6555, 0x669A, 0x66A6, 0x69A6, 0x69A9, 0x8555, 0x8556, //10-19
	0x9156, 0x9456, 0x9459, 0x9519, 0x9525, 0x9555, 0x9645, 0x9651, 0x9951, 0x9954, //20-29
	0x99A6, 0x99A9, 0x9A69, 0x9A6A, 0x9A9A, 0xC555 //30-35
];
//节气数据的索引表，数据对应“wSTSource[36]”中的索引。
//比如，起始年份（1900年）的节气数据为：wSTSource[bySTIndex[0]]，wSTSource[bySTIndex[1]],wSTSource[bySTIndex[2]]这三个16位（6字节）数据。
const bySTIndex = [
	0x12, 0x20, 0x1C, 0x14, 0x0E, 0x0C, 0x16, 0x10, 0x0D, 0x19, 0x1F, 0x19, 0x23, 0x20, 0x1C, //1900-1904
	0x14, 0x0E, 0x0C, 0x16, 0x0F, 0x0D, 0x19, 0x1F, 0x19, 0x23, 0x20, 0x1C, 0x14, 0x0E, 0x0C, //1905-1909
	0x16, 0x0F, 0x0D, 0x19, 0x1F, 0x19, 0x23, 0x20, 0x1C, 0x13, 0x0E, 0x0C, 0x14, 0x0F, 0x0D, //1910-1914
	0x18, 0x10, 0x19, 0x19, 0x20, 0x1A, 0x13, 0x0B, 0x09, 0x14, 0x0F, 0x0C, 0x18, 0x10, 0x19, //1915-1919
	0x19, 0x20, 0x1A, 0x12, 0x22, 0x09, 0x14, 0x0F, 0x0C, 0x16, 0x10, 0x19, 0x19, 0x20, 0x1A, //1920-1924
	0x12, 0x22, 0x09, 0x14, 0x0E, 0x0C, 0x16, 0x10, 0x0D, 0x19, 0x1F, 0x19, 0x12, 0x20, 0x1C, //1925-1929
	0x14, 0x0E, 0x0C, 0x16, 0x10, 0x0D, 0x19, 0x1F, 0x19, 0x12, 0x20, 0x1C, 0x14, 0x0E, 0x0C, //1930-1934
	0x16, 0x0F, 0x0D, 0x19, 0x1F, 0x19, 0x12, 0x20, 0x1C, 0x14, 0x0E, 0x0C, 0x16, 0x0F, 0x0D, //1935-1939
	0x19, 0x1F, 0x19, 0x12, 0x20, 0x1C, 0x14, 0x0E, 0x0C, 0x16, 0x0F, 0x0D, 0x19, 0x11, 0x19, //1940-1944
	0x12, 0x20, 0x1A, 0x13, 0x0E, 0x0A, 0x14, 0x0F, 0x0D, 0x18, 0x10, 0x19, 0x08, 0x20, 0x1A, //1945-1949
	0x12, 0x22, 0x0A, 0x14, 0x0F, 0x0D, 0x18, 0x10, 0x19, 0x08, 0x20, 0x1A, 0x12, 0x22, 0x09, //1950-1954
	0x14, 0x0E, 0x0C, 0x17, 0x10, 0x19, 0x08, 0x20, 0x1A, 0x12, 0x20, 0x1C, 0x14, 0x0E, 0x0C, //1955-1959
	0x16, 0x10, 0x0D, 0x08, 0x1F, 0x19, 0x12, 0x20, 0x1C, 0x14, 0x0E, 0x0C, 0x16, 0x10, 0x0D, //1960-1964
	0x08, 0x1F, 0x19, 0x12, 0x20, 0x1C, 0x14, 0x0E, 0x0C, 0x16, 0x0F, 0x0D, 0x08, 0x1F, 0x19, //1965-1969
	0x12, 0x20, 0x1C, 0x14, 0x0E, 0x0C, 0x16, 0x0F, 0x0D, 0x08, 0x11, 0x19, 0x12, 0x20, 0x1C, //1970-1974
	0x14, 0x0E, 0x0A, 0x15, 0x0F, 0x0D, 0x08, 0x10, 0x19, 0x12, 0x20, 0x1B, 0x13, 0x0B, 0x0A, //1975-1979
	0x15, 0x0F, 0x0D, 0x08, 0x10, 0x19, 0x12, 0x20, 0x1A, 0x12, 0x22, 0x0A, 0x14, 0x0E, 0x0D, //1980-1984
	0x07, 0x10, 0x19, 0x08, 0x20, 0x1A, 0x12, 0x21, 0x09, 0x14, 0x0E, 0x0C, 0x06, 0x10, 0x0D, //1985-1989
	0x08, 0x1F, 0x1A, 0x12, 0x20, 0x1C, 0x14, 0x0E, 0x0C, 0x05, 0x10, 0x0D, 0x08, 0x1F, 0x19, //1990-1994
	0x12, 0x20, 0x1C, 0x14, 0x0E, 0x0C, 0x05, 0x0F, 0x0D, 0x08, 0x1F, 0x19, 0x12, 0x20, 0x1C, //1995-1999
	0x14, 0x0E, 0x0C, 0x05, 0x0F, 0x0D, 0x08, 0x1F, 0x19, 0x12, 0x20, 0x1C, 0x14, 0x0E, 0x0C, //2000-2004
	0x05, 0x0F, 0x0D, 0x08, 0x10, 0x19, 0x12, 0x20, 0x1C, 0x14, 0x0E, 0x0A, 0x04, 0x0F, 0x0D, //2005-2009
	0x08, 0x10, 0x19, 0x12, 0x20, 0x1B, 0x14, 0x0B, 0x0A, 0x04, 0x0E, 0x0D, 0x08, 0x10, 0x19, //2010-2014
	0x12, 0x20, 0x1A, 0x12, 0x22, 0x0A, 0x03, 0x0E, 0x0D, 0x07, 0x10, 0x19, 0x08, 0x1F, 0x1A, //2015-2019
	0x12, 0x20, 0x1D, 0x03, 0x0E, 0x0C, 0x06, 0x10, 0x0D, 0x08, 0x1F, 0x1A, 0x12, 0x20, 0x1C, //2020-2024
	0x03, 0x0E, 0x0C, 0x05, 0x0F, 0x0D, 0x08, 0x1F, 0x19, 0x12, 0x20, 0x1C, 0x03, 0x0E, 0x0C, //2025-2029
	0x05, 0x0F, 0x0D, 0x08, 0x1F, 0x19, 0x12, 0x20, 0x1C, 0x03, 0x0E, 0x0C, 0x05, 0x0F, 0x0D, //2030-2034
	0x08, 0x10, 0x19, 0x12, 0x20, 0x1C, 0x03, 0x0E, 0x0C, 0x05, 0x0F, 0x0D, 0x08, 0x10, 0x19, //2035-2039
	0x12, 0x20, 0x1C, 0x03, 0x0B, 0x0A, 0x04, 0x0F, 0x0D, 0x08, 0x10, 0x19, 0x12, 0x20, 0x1B, //2040-2044
	0x02, 0x22, 0x0A, 0x04, 0x0E, 0x0D, 0x08, 0x10, 0x19, 0x12, 0x1F, 0x1A, 0x01, 0x20, 0x1D, //2045-2049
	0x03, 0x0E, 0x0D, 0x06, 0x10, 0x0D, 0x08, 0x1F, 0x1A, 0x01, 0x20, 0x1D, 0x03, 0x0E, 0x0D, //2050-2054
	0x06, 0x0F, 0x0D, 0x08, 0x1F, 0x1A, 0x01, 0x20, 0x1C, 0x03, 0x0E, 0x0C, 0x06, 0x0F, 0x0D, //2055-2059
	0x08, 0x1F, 0x19, 0x01, 0x20, 0x1C, 0x03, 0x0E, 0x0C, 0x05, 0x0F, 0x0D, 0x08, 0x1F, 0x19, //2060-2064
	0x01, 0x20, 0x1C, 0x03, 0x0E, 0x0C, 0x05, 0x0F, 0x0D, 0x08, 0x10, 0x19, 0x01, 0x20, 0x1C, //2065-2069
	0x03, 0x0B, 0x0A, 0x05, 0x0F, 0x0D, 0x08, 0x10, 0x19, 0x01, 0x20, 0x1B, 0x03, 0x0B, 0x0A, //2070-2074
	0x04, 0x0E, 0x0D, 0x08, 0x10, 0x19, 0x01, 0x20, 0x1B, 0x02, 0x21, 0x0A, 0x04, 0x0E, 0x0D, //2075-2079
	0x08, 0x10, 0x19, 0x01, 0x1F, 0x1A, 0x02, 0x20, 0x1D, 0x03, 0x0E, 0x0D, 0x06, 0x10, 0x0D, //2080-2084
	0x00, 0x1F, 0x1A, 0x01, 0x20, 0x1D, 0x03, 0x0E, 0x0D, 0x06, 0x0F, 0x0D, 0x00, 0x1F, 0x1A, //2085-2089
	0x01, 0x20, 0x1C, 0x03, 0x0E, 0x0C, 0x06, 0x0F, 0x0D, 0x00, 0x1F, 0x19, 0x01, 0x20, 0x1C, //2090-2094
	0x03, 0x0E, 0x0C, 0x05, 0x0F, 0x0D, 0x00, 0x1E, 0x19, 0x01, 0x20, 0x1C, 0x03, 0x0E, 0x0C //2095-2099
];

//---------------------------------------

//判断闰年，参数：年份，返回值：0-平年，1-闰年
function isLeapYear(year) {
	return year % 400 == 0 || (year % 100 != 0 && year % 4 == 0);
}
//检验年、月、日的合法性，参数：年，月，日，返回值：0-失败，1-成功
function checkDate(year, month, day) {
	if (year < START_YEAR || year >= END_YEAR || month > 12 || month < 1 || day < 1 || day > 31) {
		return 0;
	}
	if (month == 4 || month == 6 || month == 9 || month == 11) {
		if (day == 31) {
			return 0;
		}
	} else if (month == 2) {
		if (isLeapYear(year)) {
			if (day > 29) {
				return 0;
			}
		} else {
			if (day > 28) {
				return 0;
			}
		}
	}
	return 1;
}

//计算日期在年内的序数(距离今年元旦的天数)，参数：年，月，日，年内序数，返回值：-1-无效数据，其他-距离今年元旦的天数
function getDayOrdinal(year, month, day) {
	//从日期算出距离元旦的天数
	let ret = false;
	let nDays = -1;
	if (!checkDate(year, month, day)) //对输入的日期进行检查
	{
		return nDays;
	}

	if (isLeapYear(year)) //判断是否为闰年
	{
		nDays = DayOrdinalLeap[month - 1] + day - 1; //元旦为序数0，因此减1
	} else {
		nDays = DayOrdinal[month - 1] + day - 1;
	}

	return nDays;
}
